#include <stdlib.h>
#include <string.h>

//Include file for ACT2000
#include <applidl.h>
#include <acldev.h>
#include <aclstr.h>
#include <message.h>
#include <printer.h>

#include <logsys.h>
#include <varrec.h>
#include <eeslapi.h>

//Application specific Include files
#include "menu.h"
#include "PobTran.h"
#include "display.txo"
#include "UserIf.h"

typedef struct {
	int  ActNumber;	// Active Number/Menu? Always "1", recount automatically
	int  Direction; // Automatically Counted. 1==maju, -1==mundur, changeable; 2 maju unchangeable; -2 mundur unchangeble; 0 no direction
	long Number;	// Number for cascading menu, always "1", recount automatically
	char Name[22];
	int  inCode;	//0 ==> Next Menu  // 1-1000==>Do Op, NextMenu//>1001 ==>Do Trx, Next Menu
	char szAdditonalInfo[22];
	int  inPasswordLevel;
} SMenu;

SMenu OriginalMenu[] = {
/*	{1,0,1	, "PEMBELIAN"			,PMT_TRX_PURCHASE			,""		, 0}, */
	{1,0,1	, "TRANSFER TO"			,0							,""		, 0},
/*	{1,0,1	, "*OWN ACC"			,PMT_TRX_TRANSFER			,""		, 0}, */
	{1,0,1	, "*MERCHANT"			,PMT_TRX_PURCHASE			,""		, 0},
	{1,0,1	, "*PERMATA A/C"		,PMT_TRX_TRANSFER_REK_LAIN	,""		, 0},
	{1,0,1	, "*OTHER BANK"			,0							,""		, 0},
	{1,0,1	, "**BCA"				,PMT_TRX_TRANSFER_BANK_LAIN	,"014"	, 0},
	{1,0,1	, "**BRI"				,PMT_TRX_TRANSFER_BANK_LAIN	,"002"	, 0},
	{1,0,1	, "**BII"				,PMT_TRX_TRANSFER_BANK_LAIN	,"016"	, 0},
	{1,0,1	, "**NIAGA"				,PMT_TRX_TRANSFER_BANK_LAIN	,"022"	, 0},
	{1,0,1	, "**LIPPO"				,PMT_TRX_TRANSFER_BANK_LAIN	,"026"	, 0},
	{1,0,1	, "**DANAMON"			,PMT_TRX_TRANSFER_BANK_LAIN	,"011"	, 0},
	{1,0,1	, "**PANIN"				,PMT_TRX_TRANSFER_BANK_LAIN	,"019"	, 0},
	{1,0,1	, "**NISP"				,PMT_TRX_TRANSFER_BANK_LAIN	,"028"	, 0},
	{1,0,1	, "**BANK LAIN"			,PMT_TRX_TRANSFER_BANK_LAIN	,"0"	, 0},
	{1,0,1	, "INFORMASI"			,0							,""		, 0},
	{1,0,1	, "*SALDO"				,PMT_TRX_INFO_SALDO			,""		, 0},
	{1,0,1	, "*MINI STATEMENT"		,PMT_TRX_MINI_STATEMENT		,""		, 0},
	{1,0,1	, "*KARTU KREDIT"		,PMT_TRX_INFO_CDTCARD		,""		, 0},
	{1,0,1	, "ISI ULANG"			,PMT_TRX_ISI_ULANG			,""		, 0},
	{1,0,1	, "PEMBAYARAN"			,0							,""		, 0},
	{1,0,1	, "*TELEPON/HP"			,PMT_TRX_BAYAR_TELPON		,""		, 0},
	{1,0,1	, "*LAYANAN UMUM"		,0							,""		, 0},
	{1,0,1	, "**PLN"				,PMT_TRX_BAYAR_PLN			,""		, 0},
	{1,0,1	, "**PALYJA"			,PMT_TRX_BAYAR_PALYJA		,""		, 0},
	{1,0,1	, "**PAM BINTARO"		,PMT_TRX_BAYAR_PAM			,""		, 0},
	{1,0,1	, "*KARTU KREDIT"		,PMT_TRX_BAYAR_CDTCARD		,""		, 0},
	{1,0,1	, "*CICILAN"			,0							,""		, 0},
	{1,0,1	, "**A C C"				,PMT_TRX_CICILAN_ACC		,""		, 0},
	{1,0,1	, "**F I F"				,PMT_TRX_CICILAN_FIF		,""		, 0},
/*	{1,0,1  , "**TA FINANCE"		,PMT_TRX_CICILAN_TAF		,""		, 0},  */
/*	{1,0,1	, "**ADIRA"				,PMT_TRX_CICILAN_ADIRA		,""		, 0},  */
/*	{1,0,1	, "**PERSONAL LOAN"		,PMT_TRX_CICILAN_SCB		,""		, 0},  */
/*	{1,0,1	, "**KTA SCB"			,PMT_TRX_CICILAN_SCB		,""		, 0},  */
/*	{1,0,1	, "**KTA CITIBANK"		,PMT_TRX_CICILAN_CITI		,""		, 0},  */
	{1,0,1	, "*PENDIDIKAN"			,PMT_TRX_BAYAR_PENDIDIKAN	,"0"	, 0},
	{1,0,1	, "*ASURANSI"			,PMT_TRX_BAYAR_ASURANSI		,""		, 0},
	{1,0,1	, "*TIKET"				,0							,""		, 0},
	{1,0,1	, "**GARUDA INDONESIA"	,PMT_TRX_BAYAR_TIKET		,"020"	, 0},
/*	{1,0,1	, "**LION AIR"			,PMT_TRX_BAYAR_TIKET		,"019"	, 0},  */
	{1,0,1	, "**TIKET LAIN"		,PMT_TRX_BAYAR_TIKET		,"0"	, 0},
	{1,0,1	, "*PAY ID"				,PMT_TRX_BAYAR_PAYID		,""		, 0},
	{1,0,1	, "REGISTRASI"			,0							,""		, 0},
	{1,0,1	, "*PERMATAMOBILE"		,PMT_TRX_REGISTRASI			,""		, 0},
	{1,0,1	, "PIN & TIN"			,0							,""		, 0},
	{1,0,1	, "*PIN CHANGE"			,PMT_TRX_PIN_CHANGE			,""		, 0},
	{1,0,1	, "*TIN CREATE"			,PMT_TRX_TIN				,""		, 0},
	{1,0,1	, "*TIN CHANGE"			,PMT_TRX_TIN				,""		, 0},
	{1,0,1	, "BELANJA POIN"		,PMT_TRX_BELANJA_POIN		,""		, 0},
	{1,0,1	, "LAIN-LAIN"			,0							,""		, 0},
	{1,0,1	, "*SEND REVERSAL"		,OPT_REVERSAL				,""		, 0},
	{1,0,1	, "*REPRINT/REVIEW"		,0							,""		, 0},
	{1,0,1	, "**LAST TRANSACTION"	,OPT_REPRINT_LAST			,""		, 0},
	{1,0,1	, "**ANY TRANSACTION"	,OPT_REPRINT_ANY			,""		, 0},
	{1,0,1	, "*REPORT"				,0							,""		, 0},
	{1,0,1	, "**TODAY'S SUMMARY"	,OPT_SUMMARY_REPORT			,""		, 0},
	{1,0,1	, "**TODAY'S DETAIL"	,OPT_DETAIL_REPORT			,""		, 0},
	{1,0,1	, "**PAST REPORT"		,0							,""		, 0},
	{1,0,1	, "***SUMARRY REPORT"	,OPT_PSUM_REPORT			,""		, 0},
	{1,0,1	, "***DETAIL REPORT"	,OPT_PDTL_REPORT			,""		, 0},
	{1,0,1	, "*SELECT COMM"		,OPT_CHANGE_COMM			,""		, 0},
	{1,0,1	, "*TURN OFF"			,OPT_POWER_OFF				,""		, 0},
	{1,0,1	, "SETUP"				,OPT_VERIFY_PASSWORD		,""		, 0},
	{1,0,1	, "*DIALUP PHONE"		,0							,""		, 0},
	{1,0,1	, "**PRIMARY PHONE"		,OPT_PRIMARY_PHONE			,""		, 0},
	{1,0,1	, "**SECONDARY PHONE"	,OPT_SECONDARY_PHONE		,""		, 0},
	{1,0,1	, "*DOWNLOAD"			,0							,""		, 0},
	{1,0,1	, "**INIT PARAMETER"	,OPT_INIT_PARAMETER			,""		, 0},
	{1,0,1	, "**FULL DOWNLOAD"		,OPT_FULL_DOWNLOAD			,""		, 0},
	{1,0,1	, "*SET MASTER KEY"		,0							,""		, 0},
	{1,0,1	, "**MK MINI ATM"		,OPT_SET_MASTER_KEY			,"0"	, 0},
	{1,0,1	, "**MK FE PINPAD"		,OPT_SET_MASTER_KEY			,"1"	, 0},
	{1,0,1	, "*CLEAR REVERSAL"		,OPT_CLEAR_REVERSAL			,""		, 0},
	{1,0,1	, "*CLEAR BATCH"		,OPT_CLEAR_BATCH			,""		, 0},
	{1,0,1	, "*SELECT MENU"		,OPT_SELECT_MENU			,""		, 0},
	{1,0,1	, "*CHANGE PASSWORD"	,OPT_CHANGE_PASSWORD		,""		, 0}
/*
	{1,0,1	, "*EXIT"				,OPT_EXIT					,""		, 0},
	{1,0,1	, "*UTILITY"			,OPT_UTILITY				,""		, 0},
	{1,0,1  , "*MenuX"				,OPT_DUMMY					,""		, 0},
	{1,0,1	, "*PARTIAL DOWNLOAD"	,OPT_PARTIAL_DOWNLOAD		,""		, 0},
*/
};

SMenu Menu[sizeof(OriginalMenu)/sizeof(SMenu)+30];  //30 for additional buffer
extern TRANSACTION_OBJECT obTran;
long MenuItem = 1;
int NewTotalMenuCount = 0;  //assign by inRecountMenu();

int inMenuSelection()
{
	int inCurrPage=0;
	char buff[128];
	char szCurrFont[20];
	char szDisplayBuff[30];
	int karakter=0;
	int index;
	int inTotalMenu = sizeof(OriginalMenu)/sizeof(SMenu);
	memset(szCurrFont, 0x00, sizeof(szCurrFont));
	get_font(szCurrFont);

	memset(buff, 0x00, sizeof(buff));
	memset(buff, '1', sizeof(buff)-1);
	get_env("MENU", buff, sizeof(buff)-1);
	vdTrimSpace(buff);

	do {
		ClearSevenLine();
		set_font("F:asc4x16.vft");
		write_at("\x20\x00\x20\x20\x01", 5, 1, 4);
		set_font("");
		for (index=0; index<3; index++) {
			if (inCurrPage+index<inTotalMenu) {
				memset(szDisplayBuff, 0x00, sizeof(szDisplayBuff));
				strncpy(szDisplayBuff, "........................", 21);
				strncpy(szDisplayBuff, OriginalMenu[inCurrPage+index].Name, strlen(OriginalMenu[inCurrPage+index].Name));
				if (buff[inCurrPage+index] == '0') {strcpy(&szDisplayBuff[18], "OFF");} else {strcpy(&szDisplayBuff[19], "ON");}
				display_at(1, 3+(index*2), szDisplayBuff, NO_CLEAR);
			}
		}
		vdFlushKeyboardBuffer();
		karakter=0;
		do {
			SVC_WAIT(0);
			if (KBHIT()) karakter = get_char();
			if (karakter == 0x01) {				//F1
			} else if (karakter == 0x02) {		//F2
				if (buff[inCurrPage] == '0') {buff[inCurrPage] = '1';} else {buff[inCurrPage] = '0';}
				break;
			} else if (karakter == 0x03) {		//F3
				if (buff[inCurrPage+1] == '0') {buff[inCurrPage+1] = '1';} else {buff[inCurrPage+1] = '0';}
				break;
			} else if (karakter == 0x04) {		//F4
				if (buff[inCurrPage+2] == '0') {buff[inCurrPage+2] = '1';} else {buff[inCurrPage+2] = '0';}
				break;
			} else if (karakter == 97) {		//key_a
				if (inCurrPage+3 < inTotalMenu) inCurrPage += 3;
				break;
			} else if (karakter == 98) {		//key_b
				if (inCurrPage-3 >= 0) inCurrPage -= 3;
				break;
			} else if (karakter == 99) {		//key_c
			} else if (karakter == 100) {		//key_d
			} else if (karakter == 0x1B) {		//esc, cancel change
				return 1;
			} else if (karakter == 13) {		//enter, execute change
				break;
			} else {
				karakter = 0;
			}
		} while (1);
		if (karakter==13) break;
	} while (1);
	ClearSevenLine();
	DisplayStatus("PLEASE WAIT...");
	put_env("MENU", buff, strlen(buff));
	set_font(szCurrFont);
	inRecountMenu();
	DisplayMenu(0);
	return 1;
}

int inRecountMenu()
{
	int TotalMenuCount = sizeof(Menu)/sizeof(SMenu);
	int UnusedMenu = 0;
	SMenu NewMenu[sizeof(Menu)/sizeof(SMenu)];
	char *CharMenu;
	char Buff[128];
	int i = 0;

	LOG_PRINTFF((0x08L, "Recounting Menu..."));
	LOG_PRINTFF((0x08L, "MAXIMUM TotalMenuCount Alowed= %d", TotalMenuCount));
	CharMenu = (char *)&Menu;

	memset((void *)&Menu, 0x00, sizeof(Menu));
	memcpy((char *)&Menu, (char *)&OriginalMenu, sizeof(OriginalMenu));

	memset(Buff, 0x00, sizeof(Buff));
	memset(Buff, '1', sizeof(Buff)-1);
	get_env("MENU", Buff, sizeof(Buff)-1);
	vdTrimSpace(Buff);
	for (i=0; i<TotalMenuCount; i++) {  //Get Active/Inactive Information from config.sys
		if (Menu[i].Number>0) {
			Menu[i].ActNumber = 1;
			if (Buff[i] == '0') Menu[i].ActNumber = 0;
		}
	}

	for (i=0; i<TotalMenuCount; i++) {  //Renumbering, menu mark '*' ==> Number
	    if (i==0) {
			Menu[i].Number = 1;
	    } else if (strncmp(Menu[i].Name, "*", 1)){  //a main menu
			if (Menu[i-1].Number>=100000000L)		{ Menu[i].Number = (Menu[i-1].Number/100000000L+1);
			} else if (Menu[i-1].Number>=1000000L)	{ Menu[i].Number = (Menu[i-1].Number/1000000L+1);
			} else if (Menu[i-1].Number>=10000L)		{ Menu[i].Number = (Menu[i-1].Number/10000L+1);
			} else if (Menu[i-1].Number>=100L)		{ Menu[i].Number = (Menu[i-1].Number/100L+1);
			} else if (Menu[i-1].Number>=1L)			{ Menu[i].Number = (Menu[i-1].Number/1L+1); }
	    } else if (strncmp(Menu[i].Name, "**", 2)){ //a submenu
			if (Menu[i-1].Number>=100000000L)		{ Menu[i].Number = (Menu[i-1].Number/1000000L+1);
			} else if (Menu[i-1].Number>=1000000L)	{ Menu[i].Number = (Menu[i-1].Number/10000L+1);
			} else if (Menu[i-1].Number>=10000L)		{ Menu[i].Number = (Menu[i-1].Number/100L+1);
			} else if (Menu[i-1].Number>=100L)		{ Menu[i].Number = (Menu[i-1].Number/1L+1);
			} else if (Menu[i-1].Number>=1L)			{ Menu[i].Number = (Menu[i-1].Number*100L+1); }
			strcpy(Menu[i].Name, &Menu[i].Name[1]);
	    } else if (strncmp(Menu[i].Name, "***", 3)){ //a sub sub menu
			if (Menu[i-1].Number>=100000000L)		{ Menu[i].Number = (Menu[i-1].Number/10000L+1);
			} else if (Menu[i-1].Number>=1000000L)	{ Menu[i].Number = (Menu[i-1].Number/100L+1);
			} else if (Menu[i-1].Number>=10000L)		{ Menu[i].Number = (Menu[i-1].Number/1L+1);
			} else if (Menu[i-1].Number>=100L)		{ Menu[i].Number = (Menu[i-1].Number*100L+1);}
			strcpy(Menu[i].Name, &Menu[i].Name[2]);
	    } else if (strncmp(Menu[i].Name, "****", 4)){
			if (Menu[i-1].Number>=100000000L)		{ Menu[i].Number = (Menu[i-1].Number/100L+1);
			} else if (Menu[i-1].Number>=1000000L)	{ Menu[i].Number = (Menu[i-1].Number/1L+1);
			} else if (Menu[i-1].Number>=10000L)		{ Menu[i].Number = (Menu[i-1].Number*100L+1);}
			strcpy(Menu[i].Name, &Menu[i].Name[3]);
	    } else if (strncmp(Menu[i].Name, "*****", 5)){
			if (Menu[i-1].Number>=100000000L)		{ Menu[i].Number = (Menu[i-1].Number/1L+1);
			} else if (Menu[i-1].Number>=1000000L)	{ Menu[i].Number = (Menu[i-1].Number*100L+1);}
			strcpy(Menu[i].Name, &Menu[i].Name[4]);
		} 
		//LOG_PRINTFF((0x08L, "Menu[%d].Number = %ld", i, Menu[i].Number));
	}

	for (i=0; i<TotalMenuCount; i++) {  //Renumbering as menu start from 1, need to make it 2
		if (Menu[i].Number>=100000000L) Menu[i].Number = (Menu[i].Number/100000000L+1)*100000000L + Menu[i].Number%100000000L;
		if (Menu[i].Number>=1000000L) Menu[i].Number = (Menu[i].Number/1000000L+1)*1000000L + Menu[i].Number%1000000L;
		if (Menu[i].Number>=10000L) Menu[i].Number = (Menu[i].Number/10000L+1)*10000L + Menu[i].Number%10000L;
		if (Menu[i].Number>=100L) Menu[i].Number = (Menu[i].Number/100L+1)*100L + Menu[i].Number%100L;
		if (Menu[i].Number>=1L) Menu[i].Number = (Menu[i].Number/1L+1)*1L + Menu[i].Number%1L;
	}
	for (i=0; i<TotalMenuCount; i++) { //Insert **1, if there is **2
		if (Menu[i].Number%100==2) {
			memmove(&CharMenu[(i+1)*sizeof(SMenu)], &CharMenu[(i)*sizeof(SMenu)], (TotalMenuCount-i-1)*sizeof(SMenu));
			if (i>0) {
				memcpy(&CharMenu[i*sizeof(SMenu)], &CharMenu[(i-1)*sizeof(SMenu)], sizeof(SMenu));
				Menu[i].Number = Menu[i].Number*100+1;
				Menu[i].inCode = 0;
			} else {
				memset(&CharMenu[0], 0x00, sizeof(SMenu));
				Menu[i].Number = 1;
				Menu[i].inCode = 0;
				strcpy(Menu[i].Name, "Main");
			}
			i++;
		}
	}

	for (i=0; i<TotalMenuCount; i++){  //All Menu Header will be turn On
		if (Menu[i].Number%100==1) {
			Menu[i].ActNumber = 1;
		}
		if (Menu[i].Number==0) {  //	//Counting Unused Menu too
			UnusedMenu++;
		}
	}
	TotalMenuCount -= UnusedMenu;
	NewTotalMenuCount = TotalMenuCount;

	for (i=0; i<TotalMenuCount-1; i++) {  //Sorting Menu by Menu[i].Number
		if (Menu[i].Number > Menu[i+1].Number) {
			memcpy(&CharMenu[TotalMenuCount*sizeof(SMenu)], &CharMenu[i*sizeof(SMenu)], sizeof(SMenu));
			memcpy(&CharMenu[i*sizeof(SMenu)], &CharMenu[(i+1)*sizeof(SMenu)], sizeof(SMenu));
			memcpy(&CharMenu[(i+1)*sizeof(SMenu)], &CharMenu[TotalMenuCount*sizeof(SMenu)], sizeof(SMenu));
			i = -1;
		}
	}

	for (i=0; i<TotalMenuCount; i++){
		if (Menu[i].ActNumber == 0 && Menu[i].Number > 0) {   //find in active menu 
			long DelNum = Menu[i].Number;
			int j=0;
			for (j=i; j<TotalMenuCount; j++) { //delete inactive menu and it's submenu, rearange the Menu
				if (Menu[j].Number==DelNum ||
					Menu[j].Number/100==DelNum		|| Menu[j].Number/10000==DelNum || 
					Menu[j].Number/1000000L==DelNum	|| Menu[j].Number/100000000L==DelNum) {
					LOG_PRINTFF((0x08L, "Menu %ld [%ld.%s] Deleted", DelNum, Menu[j].Number, Menu[j].Name));
					memmove(&CharMenu[j*sizeof(SMenu)], &CharMenu[(j+1)*sizeof(SMenu)], (TotalMenuCount-j-1)*sizeof(SMenu));
					NewTotalMenuCount--;
					memset(&CharMenu[NewTotalMenuCount*sizeof(SMenu)], 0x00, sizeof(SMenu));
					j--;
				}
				if (j>=NewTotalMenuCount) break;
			}
			for (j=i; j<NewTotalMenuCount; j++) {  //Re Value the Menu Number
				if (Menu[j].Number>DelNum && Menu[j].Number<DelNum/100*100+100) { //(606/100*100+100 == 700)
					long ChangeNum = Menu[j].Number;
					int k=0;
					Menu[j].Number -= 1;
					for (k=j; k<NewTotalMenuCount; k++){  //Re value all sub menu
						if (Menu[k].Number==ChangeNum) {
							Menu[k].Number = ChangeNum;
						} else if (Menu[k].Number/100==ChangeNum) {
							Menu[k].Number = (Menu[k].Number/100-1)*100 + Menu[k].Number%100;
						} else if (Menu[k].Number/10000==ChangeNum) {
							Menu[k].Number = (Menu[k].Number/10000-1)*10000L + Menu[k].Number%10000;
						} else if (Menu[k].Number/1000000L==ChangeNum) {
							Menu[k].Number = (Menu[k].Number/1000000L-1)*1000000L + Menu[k].Number%1000000L;
						} else if (Menu[k].Number/100000000L==ChangeNum) {
							Menu[k].Number = (Menu[k].Number/100000000L-1)*100000000L + Menu[k].Number%100000000L;
						}
					}
				}
			}
			if (j>0) i--;
		}
	}
	for (i=NewTotalMenuCount-1; i>=0; i--) {  //Recalculate the menu direction
		if (Menu[i].Number%100>=5) {
			int J1 = i-Menu[i].Number%100+1;
			int Ji;
			for (Ji=0; Ji<Menu[i].Number%100; Ji++) {
				if (Ji<4) {
					Menu[J1+Ji].Direction = 2;
				} else if ((Menu[i].Number%100-((Ji)/4*4))<=4) {
					Menu[J1+Ji].Direction = -2;
				} else {
					Menu[J1+Ji].Direction = 1;
				}
			}
			i -= (Menu[i].Number%100-1);
		} else {
			Menu[i].Direction = 0;
		}
	}
	for (i=NewTotalMenuCount-1; i>=0; i--) {  //Rename custom menu
		if (!strcmp(Menu[i].Name, "TRANSFER TO")) {
			if (Menu[i].Number<100) {
				strcpy(Menu[i].Name, "TRANSFER");
			}
		}
	}

	LOG_PRINTFF((0x08L, "New TotalMenuCount = %d", NewTotalMenuCount));
	for (i=0; i<NewTotalMenuCount; i++) {
		LOG_PRINTFF((0x08, "[%ld (%d)] %s", Menu[i].Number, Menu[i].Direction, Menu[i].Name));
	}
	return 1;
}

/*
int inGetProviderAndAmount(TRANSACTION_OBJECT *pobTran)
{
	int i;
	char buff[22];
	memset(buff, 0x00, sizeof(buff));
	//strcpy(pobTran->szRcptName, Menu[pobTran->inMenuIndex].szAdditonalInfo);
	strcpy(pobTran->szAdditionalInfo, Menu[pobTran->inMenuIndex].szAdditonalInfo);
	strcpy(buff, Menu[pobTran->inMenuIndex].Name);
	for (i=0; buff[i]!=0x00; i++) {
		if (buff[i]<'0' || buff[i]>'9') {
			strcpy(&buff[i], &buff[i+1]);
			i--;
		}
	}
	pobTran->Total = atol(buff);
	pobTran->Amt = pobTran->Total;
	pobTran->Tip = 0;
	return 1;
}
*/

int inGetMenuName(char *MenuName, int MenuIndex)
{
	if (MenuIndex > 0 && MenuIndex < NewTotalMenuCount) {
		strcpy(MenuName, Menu[MenuIndex].Name);	
		return 1;
	}
	return 0; 
}

void ProcessTrans(long CurrMenuIndex)
{
	ProcessTransComplete(CurrMenuIndex);
}

void ProcessTransComplete(long CurrMenuIndex)
{
	char buff[22];
	int i = 0;
	int found = 0;
	int TotalMenuCount = NewTotalMenuCount;
//	vdFlushCardBuffer();
	vdFlushKeyboardBuffer();

	vdClearScreen();  //needed to wipe garis2 kotor di sisi kanan akibat fungsi window()
	for (i=0; i<TotalMenuCount; i++) {
		if (Menu[i].Number == CurrMenuIndex) {
			found = i;
			break;
		}
	}

	if (found) {   //Copy menu detail to POBTRAN
		memset((char *)&obTran, 0x00, sizeof(TRANSACTION_OBJECT));
		obTran.inCode = Menu[found].inCode;
		obTran.inOriginalCode = Menu[found].inCode;
		obTran.inMenuIndex = found;
		strcpy(obTran.szAdditionalInfo, Menu[found].szAdditonalInfo);
	}

	switch (Menu[found].inCode) {
		case OPT_VERIFY_PASSWORD:
			if (!inDoVerifySetup(&obTran)) {DisplayMenu(0); return;}
			break;
		case OPT_PRIMARY_PHONE:
			inDoSetupPrimaryPhone(&obTran);
			break;
		case OPT_SECONDARY_PHONE:
			inDoSetupSecondaryPhone(&obTran);
			break;
		case OPT_INIT_PARAMETER:
			inDoSetupInitParameter(&obTran);
			break;
		case OPT_PARTIAL_DOWNLOAD:
			inDoSetupPartialDownload(&obTran);
			break;
		case OPT_FULL_DOWNLOAD:
			inDoSetupFullDownload(&obTran);
			break;
		case OPT_SET_MASTER_KEY:
			inDoSetupSetMasterKey(&obTran);
			break;
		case OPT_CHANGE_BIN:
			inDoSetupChangeBIN(&obTran);
			break;
		case OPT_SELECT_MENU:
			inDoSelectMenu(&obTran);
			break;
		case OPT_CHANGE_PASSWORD:
			inDoSetupChangePassword(&obTran);
			break;
		case OPT_CLEAR_REVERSAL:
			inDoClearReversal(&obTran);
			break;
		case OPT_CLEAR_BATCH:
			inDoClearBatch(&obTran);
			break;
		case OPT_REPRINT_LAST:
			inDoReprintLastTrx(&obTran);
			break;
		case OPT_REPRINT_ANY:
			inDoReprintAnyTrx(&obTran);
			break;
		case OPT_SUMMARY_REPORT:
			inDoSummaryReport(&obTran);
			break;
		case OPT_DETAIL_REPORT:
			inDoDetailReport(&obTran);
			break;
		case OPT_PSUM_REPORT:
			inDoSummaryPastReport(&obTran);
			break;
		case OPT_PDTL_REPORT:
			inDoDetailPastReport(&obTran);
			break;
		case OPT_CHANGE_COMM:
			inDoChangeComm(&obTran);
			break;
		case OPT_POWER_OFF:
			inDoPowerOff(&obTran);
			break;
		case OPT_REVERSAL:
			inDoSendReversal(&obTran);
			break;
		case OPT_EXIT:
			inDoExit(&obTran);
			break;
		case OPT_UTILITY:
			inDoUtility(&obTran);
			break;
/*
		case TRX_INFO_SALDO:
			inDoInfomasiSaldo(&obTran);
			break;
		case TRX_PRE_TRANSFER:
			inDoTransferDana(&obTran);
			break;
		case TRX_TRANSFER:
			break;
		case TRX_PAY_CC_STD:
			//strcpy(obTran.szRcptName, Menu[obTran.inMenuIndex].Name);
			inDoBayarKartuKreditStd(&obTran);
			break;
		case TRX_PRE_PAY_PLN:
			//strcpy(obTran.szRcptName, Menu[obTran.inMenuIndex].Name);
			inDoBayarPLN(&obTran);
		case TRX_PAY_PLN:
			break;
		case TRX_PAY_PAM:
			break;
		case TRX_PRE_PAY_LLPHONE_STD:
			//strcpy(obTran.szRcptName, Menu[obTran.inMenuIndex].Name);
			//strncpy(obTran.szInfo, Menu[obTran.inMenuIndex].Name, 20);
			inDoBayarTelpon(&obTran);
		case TRX_PAY_LLPHONE_STD:
			break;
		case TRX_PAY_HPHONE_STD:
			//strcpy(obTran.szRcptName, Menu[obTran.inMenuIndex].Name);
			inDoBayarHpStd(&obTran);
			break;
		case TRX_TOPUP_STD:
			inGetProviderAndAmount(&obTran);
			inDoTopUpStd(&obTran);
			break;
		case TRX_BUY_VOUCHERHP_STD:
			inGetProviderAndAmount(&obTran);
			inDoBuyVoucherStd(&obTran);
			break;
		case TRX_MINI_STATEMENT:
			inDoMiniStatement(&obTran);
			break;
		case TRX_REGISTRASI_MB:
			inDoRegistrasiMobileBanking(&obTran);
			break;
		case TRX_PIN_CHANGE:
			inDoChangePIN(&obTran);
			break;
		case TRX_TIN_CREATE:
			inDoCreateTIN(&obTran);
			break;

		case TRX_CREDIT_POINT:
			inDoCreditPoint(&obTran);
			break;
		case TRX_CREDIT_POINT_OFFLINE:
			inDoCreditPointOffline(&obTran);
			break;
		case TRX_DEBET_POINT:
			inDoDebetPoint(&obTran);
			break;
		case TRX_INFO_POINT:
			inDoInfoPoint(&obTran);
			break;
		case OPT_OFFLINE:
			inDoSendOffline(&obTran);
			break;
*/
		case PMT_TRX_PURCHASE:					//Permata Phase I
			inDoPmtTrxPurchase(&obTran);
			break;
		case PMT_TRX_ISI_ULANG:
			inDoPmtTrxIsiUlang(&obTran);
			break;
		case PMT_TRX_REGISTRASI:
			inDoPmtTrxRegistrasi(&obTran);
			break;
		case PMT_TRX_TIN:
			inDoPmtTrxTin(&obTran);
			break;
		case OPT_DUMMY:
			inDoDummy(&obTran);
			break;
		case PMT_TRX_INFO_SALDO:
			inDoPmtTrxInfoSaldo(&obTran);
			break;
		case PMT_TRX_MINI_STATEMENT:
			inDoPmtTrxMiniStatement(&obTran);
			break;
		case PMT_TRX_INFO_CDTCARD:
			inDoPmtTrxInfoCdtCard(&obTran);
			break;
		case PMT_TRX_BAYAR_TELPON:
			inDoPmtTrxBayarTelpon(&obTran);
			break;
		case PMT_TRX_BAYAR_PLN:
			inDoPmtTrxBayarPln(&obTran);
			break;
		case PMT_TRX_BAYAR_PALYJA:
			inDoPmtTrxBayarPalyja(&obTran);
			break;
		case PMT_TRX_BAYAR_PAM:
			inDoPmtTrxBayarPam(&obTran);
			break;
		case PMT_TRX_BAYAR_CDTCARD:
			inDoPmtTrxBayarCdtCard(&obTran);
			break;
		case PMT_TRX_CICILAN_ACC:
			inDoPmtTrxCicilanAcc(&obTran);
			break;
		case PMT_TRX_CICILAN_FIF:
			inDoPmtTrxCicilanFif(&obTran);
			break;
		case PMT_TRX_CICILAN_TAF:
			inDoPmtTrxCicilanTaf(&obTran);
			break;
		case PMT_TRX_CICILAN_ADIRA:
			inDoPmtTrxCicilanAdira(&obTran);
			break;
		case PMT_TRX_CICILAN_SCB:
			inDoPmtTrxCicilanScb(&obTran);
			break;
		case PMT_TRX_CICILAN_CITI:
			inDoPmtTrxCicilanCiti(&obTran);
			break;
		case PMT_TRX_BAYAR_PENDIDIKAN:
			inDoPmtTrxBayarPendidikan(&obTran);
			break;
		case PMT_TRX_BAYAR_ASURANSI:
			inDoPmtTrxBayarAsuransi(&obTran);
			break;
		case PMT_TRX_BAYAR_TIKET:
			inDoPmtTrxBayarTiket(&obTran);
			break;
		case PMT_TRX_BAYAR_PAYID:
			inDoPmtTrxBayarPayid(&obTran);
			break;
		case PMT_TRX_TRANSFER:
			inDoPmtTrxTransfer(&obTran);
			break;
		case PMT_TRX_TRANSFER_REK_LAIN:
			inDoPmtTrxTransferRekLain(&obTran);
			break;
		case PMT_TRX_TRANSFER_BANK_LAIN:
			inDoPmtTrxTransferBankLain(&obTran);
			break;
		case PMT_TRX_PIN_CHANGE:
			inDoPmtTrxPinChange(&obTran);
			break;
		case PMT_TRX_BELANJA_POIN:
			inDoPmtTrxBelanjaPoin(&obTran);
			break;
		default:
			break;
	};
	DisplayMenu(1); //Try Next Menu if Available
	vdFlushCardBuffer();
	vdFlushKeyboardBuffer();
}


// MenuAction=0  ==> go to root menu;
// MenuAction=1  ==> go to next level menu and page=1;
// MenuAction=2  ==> back to previous level and same previous page;
// MenuAction=3  ==> move back/forward page
// MenuAction=4  ==> No Action
void DisplayMenu(int MenuAction)
{
	DisplayMenuComplete(MenuAction);
}

void DisplayMenuComplete(int MenuAction)
{
	int TotalMenuCount = NewTotalMenuCount;
	static long CurrentMenuPage = 1;   //01-99 for root menu, 01xx-99xx for sub meny, 01yyxx-99yyxx for dst				
	char MsgBuff[64];
	int found = 0;
	int i = 0;
	int MenuDirection = 0;

	if (MenuAction == 0) {
		CurrentMenuPage = 1;
	} else if (MenuAction == 1) {
		CurrentMenuPage = MenuItem*100 + 1;
	} else if (MenuAction == 2) {
		CurrentMenuPage = CurrentMenuPage/100;
	} else if (MenuAction == 3) {
		for (i=0; i<TotalMenuCount; i++) {
			if (Menu[i].Number == CurrentMenuPage) break;
		}
		if (Menu[i].Direction > 0) {
			CurrentMenuPage = CurrentMenuPage + 4;
			MenuDirection = 1;
		}
		if (Menu[i].Direction < 0) {
			CurrentMenuPage = CurrentMenuPage - 4;
			MenuDirection = -1;
		}
	} else if (MenuAction == 4){
		//CurrentMenuPage=1;
	}
	MenuItem = CurrentMenuPage = (CurrentMenuPage-1)/4 * 4 + 1;
	found=-1;
	for (i=0; i<TotalMenuCount; i++) {
		if (Menu[i].Number == CurrentMenuPage) {
			found = i;
		}
	}
	if (found==-1) {
		if (MenuAction==1) {
			CurrentMenuPage = CurrentMenuPage/100;
			MenuItem = CurrentMenuPage = (CurrentMenuPage-1)/4 * 4 + 1;
			for (i=0; i<TotalMenuCount; i++) {
				if (Menu[i].Number == CurrentMenuPage) {
					found = i;
				}
			}
		} else {
			MenuItem = CurrentMenuPage=1;
			found=1;
		}
	}
	for (i=found; (i<found+4 && i<TotalMenuCount); i++) {
		if (Menu[i].Number >= CurrentMenuPage && Menu[i].Number < CurrentMenuPage+99) {
			if ((MenuDirection) && (Menu[i].Direction == 1 || Menu[i].Direction == -1))
					Menu[i].Direction = MenuDirection;
		}
	}
	set_font("F:asc4x16.vft");
	vdClearScreen();
	for (i=0; i<TotalMenuCount; i++) {
		if (Menu[i].Number == CurrentMenuPage) {
			if (Menu[i].Direction > 0)		MsgBuff[0] = 0x00; 
			else if (Menu[i].Direction < 0) MsgBuff[0] = 0x01;
			else							MsgBuff[0] = 0x20;	
			write_at(MsgBuff,1,1,4);
			if (Menu[i].Number % 100 == 1) {
				set_font("F:asc4x16i.vft");
				memset(MsgBuff, 0x00, sizeof(MsgBuff));
				strcpy(MsgBuff, Menu[i].Name);
				if (strlen(MsgBuff)<16) strncat(MsgBuff, "                    ", 16-strlen(MsgBuff));
				write_at(MsgBuff, strlen(MsgBuff), 1, 1);
				set_font("F:asc4x16.vft");
			} else {
				write_at(Menu[i].Name, strlen(Menu[i].Name), 17-strlen(Menu[i].Name), 1);
			}
		}
		if (Menu[i].Number == CurrentMenuPage+1)
			write_at(Menu[i].Name, strlen(Menu[i].Name), 17-strlen(Menu[i].Name), 2);
		if (Menu[i].Number == CurrentMenuPage+2)
			write_at(Menu[i].Name, strlen(Menu[i].Name), 17-strlen(Menu[i].Name), 3);
		if (Menu[i].Number == CurrentMenuPage+3)
			write_at(Menu[i].Name, strlen(Menu[i].Name), 17-strlen(Menu[i].Name), 4);		
	}
	set_font("");
}

